# 声明：Python里面并没有真正的私有化，但是可以使用下划线（_）来完成伪私有化
# x 公有属性
# _x 受保护属性
# __x 私有属性
# xx_ 与系统的关键字区别
# __xx__ 系统内置的写法

# 模块的内部

# class Animal:
#     # 类的内部
#     pass
#
#
# class Dog(Animal):
#     # 子类的内部
#     pass

# 1. 受保护属性的访问限制
# 类的内部 子类的内部 可以访问 模块内 跨模块 有警告 跨模块可以使用__all__字段申明可以跨模块使用的属性

# class Animal:
#     _x = 10
#     def test(self):
#         print(Animal._x)
#         print(self._x)
#
# class Dog(Animal):
#     def test2(self):
#         print(Dog._x)
#         print(self._x)
#
# a = Animal()
# print(Animal._x)
# a.test()
#
# d = Dog()
# print(Dog._x)
# d.test2()

# 2. 私有属性的访问限制
# 只有在当前类被访问 ，不能被子类 模块内访问  跨模块访问的规则和受保护属性规则一致

# class Animal:
#     __x = 10
#     def test(self):
#         print(Animal.__x)
#         print(self.__x)
#
# class Dog(Animal):
#     def test2(self):
#         print(Dog.__x)
#         print(self.__x)

# a = Animal()
# print(Animal.__x)
# a.test()
#
# d = Dog()
# # print(Dog.__x)
# d.test2()
# print(Animal.__dict__)

# 3. 私有化属性的实现机制 ：名字重整  把__x 改为 _类名__x (_Animal__x)


# # 4. 私有化属性应用场景 数据保护 数据过滤
# class Person:
#
#     def __init__(self):
#
#         self.__age = 10
#         print(self.__dict__)
#
#     def setAge(self, value):
#         if isinstance(value, int) and 0 < value < 200:
#             self.__age = value
#         else:
#             print('您输的的数值有问题，请重新输入')
#     def getAge(self):
#         return self.__age
#
# p1 = Person()
# p1.setAge(23)
# print(p1.getAge())

# 5. 只读属性 - 一般特指实例属性 没有关键字
# 方式一: 先全部私有化  然后暴露读取方法  缺点：和常规的只读不一样 p.age  如果p.__age 是新增了一个属性
# class Person:
#     def __init__(self):
#         self.__age = 24
#         self.__weight = 140
#
#     def getAge(self):
#          return self.__age
#
#     def getWeight(self):
#         return self.__weight
#
# p = Person()
# print(p.getAge())
# print(p.getWeight())
# print(p.__dict__)

# 方式一的优化 ：  @property 装饰器 可以使用属性的方式访问属性
# class Person(object):
#     def __init__(self):
#         self.__age = 24
#         self.__weight = 140
#
#     @property
#     def age(self):
#         return self.__age
#
#     @age.setter
#     def age(self, value):
#         self.__age = value
#
#     @age.deleter
#     def age(self):
#         del self.__age
#
#     @property
#     def weight(self):
#         return self.__weight
#
# p = Person()
# p.age = 20
# print(p.age)
# print(p.weight)
# print(p.__dict__)

# 6.经典类: 没有继承（object）的类
#   新式类：继承object的类

# python2.x版本默认不继承object经典类
# python3.x 默认继承objcet 是新式类
# class Peron():
#     pass
# print(Peron.__bases__)

# 默认使用这种方式 - 使用新式类
# class Peron(object):
#     pass
# print(Peron.__bases__)


# # 7. property在新式类中的应用
#
# class Person(object):
#     def __init__(self):
#         self.__age = 10
#
#     @property
#     def age(self):
#         print('-----getter')
#         return self.__age
#
#     @age.setter
#     def age(self, value):
#         print('-----setter')
#         self.__age = value
#
# p = Person()
# print(p.age)
# p.age = 1223
# print(p.age)

# 8.property在经典类中的应用 python2.7  属性只作用了读取  不作用写入方法


# 9、只读属性的方式二  方式一中还可以_Person_age 来改
# class Person(object):
#
#     # 当我们赋值属性 = 值  自动调用这个方法 - 拦截赋值方法
#     def __setattr__(self, key, value):
#
#         # 1.判定key是不是只读属性，如果是就屏蔽增加到__dict__
#         if key == 'age' and key in self.__dict__.keys():
#             print('这个方法是只读属性')
#
#         # 2.如果不是只读，就增加到__dict__
#         else:
#
#             self.__dict__[key] = value
#
#
# p = Person()
# p.age = 10
# p.age = 12
# p.name = 'zb'
# print(p.__dict__)
# print(p.age)


# 10. 常用的系统内置属性
# __dict__ 查看属性
# __bases__ 查看所有父类的元类
# __doc__ 查看类的描述
# __name__ 查看类的名称
# __module__ 查看类定义所在的模块


# class Person(object):
#     '''
#      这是一个文档
#     '''
#     age = 18
#
#     def __init__(self):
#         self.__name = 'zb'
#
#     def run(self):
#         print('sdadfdas')

# print(Person.__dict__)
# print(Person.__bases__)
# print(Person.__doc__)
# print(Person.__name__)
# print(Person.__module__)




















